﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Principal;
using System.Runtime.InteropServices;
using Microsoft.Win32;

namespace Utility
{
/// <summary>
    /// Klasa bada cechy systemu operacyjnego .
    /// </summary>
    public static class Windows
    {
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
        public const int SW_MINIMIZE = 6;
        public const int SW_MAXIMIZE = 3;
        public const int SW_RESTORE = 9;
        public const int SW_HIDE = 0;

        /// <summary>
        /// method for checking to see if the logged in user
        /// is in the Administrator's group
        /// </summary>
        /// <returns></returns>
        public static bool IsUserAdministrator()
        {
            //bool value to hold our return value
            bool isAdmin;
            try
            {
                //get the currently logged in user
                WindowsIdentity user = WindowsIdentity.GetCurrent();
                WindowsPrincipal principal = new WindowsPrincipal(user);
                isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);
            }
            catch (UnauthorizedAccessException ex)
            {
                isAdmin = false;
            }
            catch (Exception ex)
            {
                isAdmin = false;
            }
            return isAdmin;
        }


        /// <summary>
        /// Typ wyliczeniowy zawierający wersjie systemów 
        /// </summary>
        public enum WindowsType
        {
            System_nie_znany = 0,
            Windows_95_OSR2,
            Windows_95,
            Windows_98_Second_Edition,
            Windows_98,
            Windows_Me,
            Windows_NT_3_51,
            Windows_NT_40,
            Windows_NT_40_Server,
            Windows_2000,
            Windows_XP,
            Windows_2003_Server,
            Windows_Vista,
            Windows_2008_Server
        }

        /// <summary>
        /// Struktura używana przez GetVersionEx i VerifyVersionInfo
        /// Zawiera informacje o numerze głównej i dodtkowej wersji systemu,
        /// numer budowy , identifikator platformy oraz informacje o
        /// product suite i ostatniej wersji Service Pack
        /// </summary>
        public struct OSVERSIONINFOEX
        {
            /// <summary>
            /// Rozmiar struktury ,ustaw to pole na sizeof(OSVERSIONINFOEX);
            /// </summary>
            public int dwOSVersionInfoSize;

            /// <summary>
            /// numer głównej wersji systemu operacyjnego
            /// </summary>
            public int dwMajorVersion;

            /// <summary>
            /// numer mniejszej wersji systemu operacujnego
            /// </summary>
            public int dwMinorVersion;

            /// <summary>
            /// Numer budowy systemu operacyjnego
            /// </summary>
            public int dwBuildNumber;

            /// <summary>
            /// Platforma systemu operacyjnego 
            /// </summary>
            public int dwPlatformId;

            /// <summary>
            ///  Tekst informujący o ostatniej wersji Service Pack - pusty jeśli brak
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
            public string szCSDVersion;

            /// <summary>
            /// numer ostatnio zainstalowanej głównej versji Service Pack
            /// </summary>
            public short wServicePackMajor;

            /// <summary>
            /// numer ostatnio zainstalowanej mniejszej versji Service Pack
            /// </summary>
            public short wServicePackMinor;

            /// <summary>
            /// bit maska identyfikujaca kombinację product suite dostępnych w systemie 
            /// </summary>
            public short wSuiteMask;

            /// <summary>
            /// dodatkowe informacje o systemie
            /// </summary>
            public byte wProductType;

            /// <summary>
            /// zarezerwowane na przyszłość
            /// </summary>
            public byte wReserved;
        }

        [DllImport("kernel32.dll")]
        private static extern bool GetVersionEx(ref OSVERSIONINFOEX osVersionInfo);

        /// <summary>
        /// Rozpoznaje wersję systemu operacyjnego
        /// </summary>
        /// <returns>machineOS typu wyliczeniowego WindowsType zawiera wersję systemu operacyjnego</returns>
        public static WindowsType GetMachineOS()
        {
            WindowsType machineOS = WindowsType.System_nie_znany;
            OperatingSystem osVersion = Environment.OSVersion;
            OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX();
            osVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEX));
            if (GetVersionEx(ref osVersionInfo))
            {
                int majorVersion = osVersion.Version.Major;
                int minorVersion = osVersion.Version.Minor;

                switch (osVersion.Platform)
                {
                    case PlatformID.Win32Windows:
                        {
                            if (majorVersion == 4)
                            {
                                string csdVersion = osVersionInfo.szCSDVersion;
                                switch (minorVersion)
                                {
                                    case 0:
                                        if (csdVersion == "B" || csdVersion == "C")
                                        {
                                            machineOS = WindowsType.Windows_95_OSR2;
                                        }
                                        else
                                        {
                                            machineOS = WindowsType.Windows_95;
                                        }

                                        break;
                                    case 10:
                                        if (csdVersion == "A")
                                        {
                                            machineOS = WindowsType.Windows_98_Second_Edition;
                                        }
                                        else
                                        {
                                            machineOS = WindowsType.Windows_98;
                                        }

                                        break;
                                    case 90:
                                        machineOS = WindowsType.Windows_Me;
                                        break;
                                }
                            }

                            break;
                        }

                    case PlatformID.Win32NT:
                        {
                            byte productType = osVersionInfo.wProductType;
                            switch (majorVersion)
                            {
                                case 3:
                                    machineOS = WindowsType.Windows_NT_3_51;
                                    break;
                                case 4:
                                    switch (productType)
                                    {
                                        case 1:
                                            machineOS = WindowsType.Windows_NT_40;
                                            break;
                                        case 3:
                                            machineOS = WindowsType.Windows_NT_40_Server;
                                            break;
                                    }

                                    break;
                                case 5:
                                    switch (minorVersion)
                                    {
                                        case 0:
                                            machineOS = WindowsType.Windows_2000;
                                            break;
                                        case 1:
                                            machineOS = WindowsType.Windows_XP;
                                            break;
                                        case 2:
                                            machineOS = WindowsType.Windows_2003_Server;
                                            break;
                                    }

                                    break;
                                case 6:
                                    switch (productType)
                                    {
                                        case 1:
                                            machineOS = WindowsType.Windows_Vista;
                                            break;
                                        case 3:
                                            machineOS = WindowsType.Windows_2008_Server;
                                            break;
                                    }

                                    break;
                            }

                            break;
                        }
                }
            }

            return machineOS;
        }

        /// <summary>
        /// Reads path of default browser from registry
        /// </summary>
        /// <returns></returns>
        private static string GetDefaultBrowserPath()
        {
            string key = @"http\shell\open\command";
            Microsoft.Win32.RegistryKey registryKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(key, false);
            // get default browser path
            return StringToPath(((string)registryKey.GetValue(null, null)));
        }

        private static string StringToPath(string str)
        {
            char chPathEnd = ' ';
            int diff = 0;
            if (str[0] == '"')
            {
                chPathEnd = '"';
                diff = 1;
            }
            for (int i = 1; i < str.Length; i++)
                if (str[i] == chPathEnd)
                    return str.Substring(diff, i - diff);
            return str;
        }
    }

    
}
